package com.bsoft.advance.client.proxy;

import com.bsoft.advance.core.common.RpcClientProperties;
import com.bsoft.advance.core.register.DiscoveryService;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 通过CGLIB，为接口生成代理类
 */
public class CGlibRpcProxy implements RpcProxy{
    @Override
    public <T> T proxyInterface(RpcClientProperties properties, DiscoveryService discoveryService, Class<T> clazz) {
        Enhancer enhancer = new Enhancer();
        if (clazz.isInterface()) {
            enhancer.setInterfaces(new Class[]{clazz});
        }else{
            enhancer.setSuperclass(clazz);
        }
        enhancer.setCallback(new CGlibProxyInterceptor(clazz, properties, discoveryService));
        return (T)enhancer.create();
    }


    public class CGlibProxyInterceptor implements MethodInterceptor{
        private Class<?> clazz;
        private RpcClientProperties properties;
        private DiscoveryService discoveryService;

        public CGlibProxyInterceptor(Class<?> clazz, RpcClientProperties properties, DiscoveryService discoveryService) {
            this.clazz = clazz;
            this.properties = properties;
            this.discoveryService = discoveryService;
        }

        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            return RpcRequestHandler.invokeRequest(properties, discoveryService, clazz, method, objects);
        }
    }
}
